home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / Xconq 7.1.0 / src / xconq-7.1.0 / kernel / skelconq.c < prev    next >
Encoding:
Text File  |  1996-07-07  |  25.2 KB  |  1,042 lines  |  [TEXT/R*ch]

  1. /* A minimal interface to Xconq.
  2.    Copyright (C) 1991, 1992, 1993, 1994, 1995 Stanley T. Shebs.
  3.  
  4. Xconq is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.  See the file COPYING.  */
  8.  
  9. /* This interface uses only what is
  10.    required by ANSI, so it should run just about everywhere without
  11.    any changes.  This is most useful for testing the kernel and game
  12.    design libraries.
  13.  
  14.    This file can also serve as a starting point for writing a new interface,
  15.    since it has simple or default implementations of the routines that any
  16.    interface has to support. */
  17.  
  18. #include "conq.h"
  19. extern void low_send PARAMS ((int id, char *buf));
  20. extern int low_receive PARAMS ((int *id, char *buf, int maxchars,
  21.                 int timeout));
  22. #include "print.h"
  23. #include "cmdline.h"
  24.  
  25. #ifdef COMPILER
  26. extern void compile PARAMS ((void));
  27. #endif /* COMPILER */
  28.  
  29. static void init_displays PARAMS ((void));
  30. static void get_input PARAMS ((void));
  31. static void interpret_command PARAMS ((Obj *cmd));
  32. static void list_one_unit PARAMS ((Unit *unit));
  33. static void interpret_help PARAMS ((Side *side, char *str));
  34. static int do_cmd PARAMS ((Side *side, Obj *cmd, Obj *parms));
  35. #ifdef DEBUGGING
  36. static void toggle_debug PARAMS ((Side *side, Obj *cmd, Obj *parms));
  37. static void toggle_debugg PARAMS ((Side *side, Obj *cmd, Obj *parms));
  38. static void toggle_debugm PARAMS ((Side *side, Obj *cmd, Obj *parms));
  39. #endif /* DEBUGGING */
  40. static void list_sides PARAMS ((Side *side, Obj *cmd, Obj *parms));
  41. static void list_units PARAMS ((Side *side, Obj *cmd, Obj *parms));
  42. static void list_actors PARAMS ((Side *side, Obj *cmd, Obj *parms));
  43. static void list_cells PARAMS ((Side *side, Obj *cmd, Obj *parms));
  44. static void do_task_cmd PARAMS ((Side *side, Obj *cmd, Obj *parms));
  45. static void do_finish_turn PARAMS ((Side *side, Obj *cmd, Obj *parms));
  46. static void do_finish_all PARAMS ((Side *side, Obj *cmd, Obj *parms));
  47. static voiefaultside = side;
  48.     set_autofinish(side, FALSE);
  49.     DGprintf("Created a UI for %s\n", side_desig(side));
  50.     } else {
  51.     side->ui = NULL;
  52.     }
  53. }
  54.  
  55. /* This tests whether the side has a display and if it is in use. */
  56.  
  57. int
  58. active_display(side)
  59. Side *side;
  60. {
  61.     return (side && side_has_display(side) && side->ui->active);
  62. }
  63.  
  64. /* Input reading waits for a number of sides, possibly times out. */
  65.  
  66. static void
  67. get_input()
  68. {
  69.     int cmdlineno = 1, endlineno = 1;
  70.     Obj *cmd;
  71.     Side *side = NULL;
  72.  
  73.     if (realtime_game()) {
  74.     for_all_sides(side) {
  75.         update_clock_display(side, TRUE);
  76.     }
  77.     }
  78.     /* should say which sides we're waiting for */
  79.     printf("> ");
  80.     fflush(stdout);
  81.     if (repetition-- > 0) {
  82.     cmd = multicmd;
  83.     } else {
  84.     cmd = read_form(stdin, &cmdlineno, &endlineno);
  85.     }
  86.     if (cmd != lispeof) {
  87.     Dprintlisp(cmd);
  88.     interpret_command(cmd);
  89.     } else {
  90.     printf("EOF reached\n");
  91.     /* should just close one display, leave others running */
  92.     exit(0);
  93.     }
  94. }
  95.  
  96. Unit *thisunit;
  97.  
  98. /* Do some simple command parsing, just enough to exercise the program. */
  99.  
  100. static void
  101. interpret_command(origcmd)
  102. Obj *origcmd;
  103. {
  104.     char *str;
  105.     Obj *cmd, *verb = lispnil, *parms = lispnil;
  106.     Side *side = NULL;
  107.     Unit *unit = NULL;
  108.  
  109.     thisunit = NULL;
  110.     cmd = origcmd;
  111.     if (consp(cmd) && numberp(car(cmd))) {
  112.     side = side_n(c_number(car(cmd)));
  113.     cmd = cdr(cmd);
  114.     }
  115.     if (consp(cmd) && numberp(car(cmd))) {
  116.     unit = find_unit(c_number(car(cmd)));
  117.     thisunit = unit;
  118.     cmd = cdr(cmd);
  119.     }
  120.     if (consp(cmd)) {
  121.     verb = car(cmd);
  122.     parms = cdr(cmd);
  123.     } else if (symbolp(cmd)) {
  124.     verb = cmd;
  125.     }
  126.     if (verb == lispnil) {
  127.     } else if (do_cmd(side, verb, parms)) {
  128.     } else if (do_action(side, unit, verb, parms)) {
  129.     } else if (symbolp(verb) && *(str = c_string(verb)) == '?') {
  130.     interpret_help(side, str+1);
  131.     } else {
  132.     printf("Command ");
  133.     fprintlisp(stdout, origcmd);
  134.     printf(" not understood, ignoring it\n");
  135.     }
  136. }
  137.  
  138. /* Random commands. */
  139.  
  140. static void
  141. toggle_debug(side, cmd, parms)
  142. Side *side;
  143. Obj *cmd, *parms;
  144. {
  145.     if (parms == lispnil) {
  146.     Debug = !Debug;
  147.     } else if (symbolp(car(parms)) && equal(car(parms), intern_symbol("on"))) {
  148.     Debug = TRUE;
  149.     } else {
  150.     Debug = FALSE;
  151.     }
  152. }
  153.  
  154. static void
  155. toggle_debugm(side, cmd, parms)
  156. Side *side;
  157. Obj *cmd, *parms;
  158. {
  159.     if (parms == lispnil) {
  160.     DebugM = !DebugM;
  161.     } else if (symbolp(car(parms)) && equal(car(parms), intern_symbol("on"))) {
  162.     DebugM = TRUE;
  163.     } else {
  164.     DebugM = FALSE;
  165.     }
  166. }
  167.  
  168. static void
  169. toggle_debugg(side, cmd, parms)
  170. Side *side;
  171. Obj *cmd, *parms;
  172. {
  173.     if (parms == lispnil) {
  174.     DebugG = !DebugG;
  175.     } else if (symbolp(car(parms)) && equal(car(parms), intern_symbol("on"))) {
  176.     DebugG = TRUE;
  177.     } else {
  178.     DebugG = FALSE;
  179.     }
  180. }
  181.  
  182. static void
  183. list_sides(side, cmd, parms)
  184. Side *side;
  185. Obj *cmd, *parms;
  186. {
  187.     int u;
  188.     Side *side2;
  189.     Agreement *ag;
  190.     extern int numagreements;
  191.  
  192.     printf("Sides:\n");
  193.     for_all_sides(side2) {
  194.     printf("%s played by %s\n",
  195.            side_desig(side2), player_desig(side2->player));
  196.     if (using_tech_levels()) {
  197.         printf("Tech:");
  198.         for_all_unit_types(u) {
  199.         if (u_tech_max(u) > 0) {
  200.             printf("  %s %d/%d",
  201.                u_type_name(u), side2->tech[u], u_tech_max(u));
  202.         }
  203.         }
  204.         printf("\n");
  205.     }
  206.     /* (should say something about mplayer goals here) */
  207.     }
  208.     if (numagreements > 0) {
  209.     printf("Agreements:\n");
  210.     for_all_agreements(ag) {
  211.         printf("%s\n", agreement_desig(ag));
  212.     }
  213.     }
  214. }
  215.  
  216. static void
  217. list_units(side, cmd, parms)
  218. Side *side;
  219. Obj *cmd, *parms;
  220. {
  221.     Unit *unit;
  222.  
  223.     printf("Units:\n");
  224.     for_all_units(unit) {
  225.     list_one_unit(unit);
  226.     }
  227. }
  228.  
  229. static void
  230. list_actors(side, cmd, parms)
  231. Side *side;
  232. Obj *cmd, *parms;
  233. {
  234.     int i;
  235.     Side *side2;
  236.     Unit *unit;
  237.  
  238.     printf("Actors (listed by side):\n");
  239.     for_all_sides(side2) {
  240.     printf("%s: %s\n",
  241.            side_desig(side2),
  242.            (side2->finishedturn ? "(finished)" : ""));
  243.     }
  244.     for_all_sides_plus_indep(side2) {
  245.     for (i = 0; i < side2->actionvector->numunits; ++i) {
  246.         unit = (side2->actionvector->units)[i].unit;
  247.         list_one_unit(unit);
  248.     }
  249.     }
  250. }
  251.  
  252. static void
  253. list_one_unit(unit)
  254. Unit *unit;
  255. {
  256.     char status[BUFSIZE];
  257.  
  258.     if (unit == NULL) {
  259.     printf("  -\n");
  260.     return;
  261.     }
  262.     if (!completed(unit)) {
  263.     sprintf(status, " cp %d ", unit->cp);
  264.     } else if (unit->hp < u_hp(unit->type)) {
  265.     sprintf(status, " hp %d ", unit->hp);
  266.     } else {
  267.     sprintf(status, " ");
  268.     }
  269.     printf("  %s%s%s %s\n",
  270.        unit_desig(unit), status,
  271.        actorstate_desig(unit->act), plan_desig(unit->plan));
  272. }
  273.  
  274. static void
  275. list_cells(side, cmd, parms)
  276. Side *side;
  277. Obj *cmd, *parms;
  278. {
  279.     int x = c_number(car(parms)), y = c_number(cadr(parms));
  280.  
  281.     printf("At %d,%d", x, y);
  282.     if (in_area(x, y)) {
  283.     printf(", terrain %s", t_type_name(terrain_at(x, y)));
  284.     /* (dump borders?) */
  285.     printf(", elev %d", elev_at(x, y));
  286.     printf(", temp %d", temperature_at(x, y));
  287.     /* (etc) */
  288.     } else {
  289.     printf(" - outside area!");
  290.     }
  291.     printf("\n");
  292. }
  293.  
  294. static void
  295. do_task_cmd(side, cmd, parms)
  296. Side *side;
  297. Obj *cmd, *parms;
  298. {
  299.     int i, j, numargs;
  300.     char *taskname;
  301.     Obj *tasksym = car(parms), *taskparms = cdr(parms);
  302.     Task *task;
  303.  
  304.     if (symbolp(tasksym)) {
  305.     taskname = c_string(tasksym);
  306.     /* Iterate through task names looking for a match. */
  307.     for (i = 0; taskdefns[i].name != NULL; ++i) {
  308.         if (strcmp(taskname, taskdefns[i].name) == 0) {
  309.         if (thisunit != NULL && thisunit->plan != NULL) {
  310.             task = create_task(i);
  311.             numargs = strlen(taskdefns[i].argtypes);
  312.             for (j = 0; j < numargs; ++j) {
  313.             if (taskparms != lispnil) {
  314.                 task->args[j] = c_number(car(taskparms));
  315.                 taskparms = cdr(taskparms);
  316.             } else {
  317.                 task->args[j] = 0;
  318.             }
  319.             }
  320.             task->next = thisunit->plan->tasks;
  321.             thisunit->plan->tasks = task;
  322.             thisunit->plan->waitingfortasks = FALSE;
  323.         }
  324.         return;
  325.         }
  326.     }
  327.     fprintf(stderr, "Task type \"%s\" not recognized\n", taskname);
  328.     }
  329. }
  330.  
  331. static void
  332. do_finish_turn(side, cmd, parms)
  333. Side *side;
  334. Obj *cmd, *parms;
  335. {
  336.     if (side) {
  337.     finish_turn(side);
  338.     } else {
  339.     fprintf(stderr, "No side?\n");
  340.     }
  341. }
  342.  
  343. static void
  344. do_finish_all(side, cmd, parms)
  345. Side *side;
  346. Obj *cmd, *parms;
  347. {
  348.     Side *side2;
  349.  
  350.     for_all_sides(side2) {
  351.     finish_turn(side2);
  352.     }
  353. }
  354.  
  355. static void
  356. do_free_run(side, cmd, parms)
  357. Side *side;
  358. Obj *cmd, *parms;
  359. {
  360.     freerunturns = c_number(car(parms));
  361. }
  362.  
  363. static void
  364. do_repeat(side, cmd, parms)
  365. Side *side;
  366. Obj *cmd, *parms;
  367. {
  368. }
  369.  
  370. static void
  371. do_multiple(side, cmd, parms)
  372. Side *side;
  373. Obj *cmd, *parms;
  374. {
  375.     repetition = c_number(car(parms));
  376.     multicmd = cdr(parms);
  377. }
  378.  
  379. static void
  380. do_save(side, cmd, parms)
  381. Side *side;
  382. Obj *cmd, *parms;
  383. {
  384.     if (!write_entire_game_state(saved_game_filename())) {
  385.     fprintf(stderr, "Save failed.\n");
  386.     }
  387. }
  388.  
  389. static void
  390. do_eval(side, cmd, parms)
  391. Side *side;
  392. Obj *cmd, *parms;
  393. {
  394.     interp_form(NULL, car(parms));
  395. }
  396.  
  397. static void
  398. do_help(side, cmd, parms)
  399. Side *side;
  400. Obj *cmd, *parms;
  401. {
  402.     printf("To look at help topics, type \"?<letter>\",\n");
  403.     printf("where 'n' and 'p' go to next and previous nodes\n");
  404. }
  405.  
  406. static void
  407. do_print(side, cmd, parms)
  408. Side *side;
  409. Obj *cmd, *parms;
  410. {
  411.     char *fname;
  412.     FILE *fp;
  413.  
  414.     if (parms != lispnil) {
  415.     if (stringp(car(parms))) {
  416.         fname = c_string(car(parms));
  417.         if ((fp = fopen(fname, "w")) != NULL) {
  418.         print_game_description_to_file(fp);
  419.         fclose(fp);
  420.         } else {
  421.         fprintf(stderr, "couldn't open \"%s\"\n", fname);
  422.         }
  423.     } else {
  424.         /* error, not a string */
  425.     }
  426.     } else {
  427.     print_game_description_to_file(stdout);
  428.     }
  429. }
  430.  
  431. static void
  432. do_memory(side, cmd, parms)
  433. Side *side;
  434. Obj *cmd, *parms;
  435. {
  436.     extern int grandtotmalloc;
  437.  
  438.     printf("%d bytes allocated.\n", grandtotmalloc);
  439. }
  440.  
  441. /* Exit immediately, no questions asked. */
  442.  
  443. static void
  444. do_quit(side, cmd, parms)
  445. Side *side;
  446. Obj *cmd, *parms;
  447. {
  448.     printf("Quitting.\n");
  449.     exit(0);
  450. }
  451.  
  452. #ifdef COMPILER
  453. static void
  454. do_compile(side, cmd, parms)
  455. Side *side;
  456. Obj *cmd, *parms;
  457. {
  458.     compile();
  459. }
  460. #endif /* COMPILER */
  461.  
  462. struct a_cmd {
  463.     char *cmd;
  464.     void (*fn) PARAMS ((Side *side, Obj *cmd, Obj *parms));
  465. } cmdtable[] = {
  466.     { "debug", toggle_debug },
  467.     { "debugm", toggle_debugm },
  468.     { "debugg", toggle_debugg },
  469.     { "sides", list_sides },
  470.     { "units", list_units },
  471.     { "actors", list_actors },
  472.     { "cells", list_cells },
  473.     { "task", do_task_cmd },
  474.     { "fin", do_finish_turn },
  475.     { "finall", do_finish_all },
  476.     { "again", do_repeat },
  477.     { "*", do_multiple },
  478.     { "run", do_free_run },
  479.     { "save", do_save },
  480.     { "eval", do_eval },
  481.     { "help", do_help },
  482.     { "print", do_print },
  483.     { "memory", do_memory },
  484.     { "quit", do_quit },
  485. #ifdef COMPILER
  486.     { "compile", do_compile },
  487. #endif /* COMPILER */
  488.     { NULL, NULL }
  489. };
  490.  
  491. /* Try to find and execute an arbitrary command. */
  492.  
  493. static int
  494. do_cmd(side, cmd, parms)
  495. Side *side;
  496. Obj *cmd, *parms;
  497. {
  498.     struct a_cmd *cmdentry = cmdtable;
  499.     char *cmdstr;
  500.  
  501.     if (!symbolp(cmd)) return FALSE;
  502.     cmdstr = c_string(cmd);
  503.     while (cmdentry->cmd != NULL) {
  504.     if (strcmp(cmdstr, cmdentry->cmd) == 0) {
  505.         (*(cmdentry->fn))(side, cmd, parms);
  506.         return TRUE;
  507.     }
  508.     ++cmdentry;
  509.     }
  510.     return FALSE;
  511. }
  512.  
  513. static int
  514. do_action(side, unit, cmd, args)
  515. Side *side;
  516. Unit *unit;
  517. Obj *cmd, *args;
  518. {
  519.     int randomact = FALSE;
  520.     ActionDefn *actdefn = actiondefns;
  521.     char *cmdstr, *argstr;
  522.     char localbuf[BUFSIZE];
  523.     int i = 0, rslt;
  524.     Obj *rest;
  525.     Action action;
  526.  
  527.     if (!symbolp(cmd)) return FALSE;
  528.     cmdstr = c_string(cmd);
  529.     if (side == NULL) {
  530.     side = defaultside;
  531.     if (side == NULL) {
  532.         fprintf(stderr, "Using first side since no defaults avail\n");
  533.         side = sidelist->next;
  534.     }
  535.     }
  536.     if (unit == NULL) {
  537.     /* (think of something to do here) */
  538.     }
  539.     while (actdefn->name != NULL) {
  540.     if (strcmp(cmdstr, actdefn->name) == 0) {
  541.         memset(&action, 0, sizeof(Action));
  542.         action.type = actdefn->typecode;
  543.         /* Special option to generate random args to action. */
  544.         if (symbolp(car(args))
  545.         && strcmp("randomly", c_string(car(args))) == 0) {
  546.         args = cdr(args);
  547.         randomact = TRUE;
  548.         }
  549.         if (unit == NULL) {
  550.         if (randomact) {
  551.             while (!((unit = find_unit(xrandom(numunits))) != NULL
  552.                  && (unit->act != NULL || flip_coin()))
  553.                && probability(99));
  554.             if (unit == NULL) {
  555.             fprintf(stderr, "Can't find a unit to act!\n");
  556.             /* We're out of luck, just give up. */
  557.             return TRUE;
  558.             }
  559.         } else {
  560.             fprintf(stderr, "No unit to %s!\n", cmdstr);
  561.             /* *Command* *was* valid, just the args were bad. */
  562.             return TRUE;
  563.         }
  564.         }
  565.         /* Move args from list into action. */
  566.         argstr = actdefn->argtypes;
  567.         for (rest = args; rest != lispnil; rest = cdr(rest)) {
  568.         if (argstr[i] != '\0') {
  569.             action.args[i] = c_number(car(rest));
  570.         } else {
  571.             break;
  572.         }
  573.         ++i;
  574.         }
  575.         if (i != strlen(argstr)) {
  576.         if (randomact) {
  577.             make_plausible_random_args(argstr, i, &(action.args[0]),
  578.                            unit);
  579.         } else {
  580.             printf("Mismatched args!\n");
  581.             return TRUE;
  582.         }
  583.         }
  584.         sprintf(localbuf, "%s tries %s",
  585.             unit_desig(unit), action_desig(&action));
  586.         rslt = execute_action(unit, &action);
  587.         printf("%s - %s\n", localbuf, hevtdefns[rslt].name);
  588.         return TRUE;
  589.     }
  590.     ++actdefn;
  591.     }
  592.     return FALSE;
  593. }
  594.  
  595. /* Shut down displays - should be done before any sort of exit. */
  596.  
  597. void
  598. close_displays()
  599. {
  600.     Side *side;
  601.  
  602.     for_all_sides(side) {
  603.     if (active_display(side)) {
  604.         side->ui->active = FALSE;
  605.         printf("Display \"%s\" closed.\n", side->player->displayname);
  606.     }
  607.     }
  608. }
  609.  
  610. void
  611. low_notify(side, str)
  612. Side *side;
  613. char *str;
  614. {
  615.     printf("To %s: %s\n", side_desig(side), str);
  616. }
  617.  
  618. /* (should count # of calls to inactive and non-displayed side...) */
  619.  
  620. void
  621. update_cell_display(side, x, y, rightnow)
  622. Side *side;
  623. int x, y;
  624. int rightnow;
  625. {
  626.     ++numcellupdatesperturn;
  627.     if (active_display(side)) {
  628.     ++numusefulcellupdatesperturn;
  629.     DGprintf("To %s: update view of %d,%d%s\n",
  630.          side_desig(side), x, y, (rightnow ? " (now)" : ""));
  631.     }
  632. }
  633.  
  634. /* This hook updates any display of the current turn/date, and any
  635.    other global info, as needed. */
  636.  
  637. void
  638. update_turn_display(side, rightnow)
  639. Side *side;
  640. int rightnow;
  641. {
  642.     long secs;
  643.     time_t xxx;
  644.  
  645.     if (active_display(side)) {
  646.     time(&xxx);
  647.     secs = idifftime(xxx, skelturnstart);
  648.     printf("To %s: update to turn %d (%ld seconds since last)",
  649.            side_desig(side), g_turn(), secs);
  650.     DGprintf("%s", (rightnow ? " (now)" : ""));
  651.     printf("\n");
  652.     printf("%d cell updates, %d useful\n",
  653.            numcellupdatesperturn, numusefulcellupdatesperturn);
  654.     numcellupdatesperturn = numusefulcellupdatesperturn = 0;
  655.     skelturnstart = xxx;
  656.     --freerunturns;
  657.     if (rightnow) fflush(stdout);
  658.     }
  659. }
  660.  
  661. void
  662. update_action_display(side, rightnow)
  663. Side *side;
  664. int rightnow;
  665. {
  666.     if (active_display(side) && DebugG) {
  667.     printf("To %s: ready to act\n", side_desig(side));
  668.     }
  669. }
  670.  
  671. void
  672. update_action_result_display(side, unit, rslt, rightnow)
  673. Side *side;
  674. Unit *unit;
  675. int rslt, rightnow;
  676. {
  677.     if (active_display(side) && DebugG) {
  678.     printf("To %s: %s action result is %s\n",
  679.            side_desig(side), unit_desig(unit), hevtdefns[rslt].name);
  680.     }
  681. }
  682.  
  683. /* This is for animation of fire-at actions. */
  684.  
  685. void
  686. update_fire_at_display(side, unit, unit2, m, rightnow)
  687. Side *side;
  688. Unit *unit, *unit2;
  689. int m, rightnow;
  690. {
  691. }
  692.  
  693. /* This is for animation of fire-into actions. */
  694.  
  695. void
  696. update_fire_into_display(side, unit, x, y, z, m, rightnow)
  697. Side *side;
  698. Unit *unit;
  699. int x, y, z, m, rightnow;
  700. {
  701. }
  702.  
  703. void
  704. update_event_display(side, hevt, rightnow)
  705. Side *side;
  706. HistEvent *hevt;
  707. int rightnow;
  708. {
  709.     if (active_display(side)) {
  710.     switch (hevt->type) {
  711.       case H_SIDE_LOST:
  712.         printf("%s lost!\n", side_desig(side_n(hevt->data[0])));
  713.         break;
  714.       case H_SIDE_WON:
  715.         printf("%s won!\n",  side_desig(side_n(hevt->data[0])));
  716.         break;
  717.       default:
  718.         DGprintf("To %s: event %s %d\n",
  719.              side_desig(side), hevtdefns[hevt->type].name,
  720.              hevt->data[0]);
  721.     }
  722.     }
  723. }
  724.  
  725. void
  726. update_all_progress_displays(str, s)
  727. char *str;
  728. int s;
  729. {
  730. }
  731.  
  732. /* This hook should update the side's view of the given side, no matter
  733.    who it belongs to. */
  734.  
  735. void
  736. update_side_display(side, side2, rightnow)
  737. Side *side, *side2;
  738. int rightnow;
  739. {
  740.     char *side2desc = copy_string(side_desig(side2));
  741.  
  742.     if (active_display(side) && DebugG) {
  743.     printf("To %s: update side %s%s\n",
  744.            side_desig(side), side2desc, (rightnow ? " (now)" : ""));
  745.     }
  746. }
  747.  
  748. /* This hook should update the side's view of the given unit, no matter
  749.    who it belongs to. */
  750.  
  751. void
  752. update_unit_display(side, unit, rightnow)
  753. Side *side;
  754. Unit *unit;
  755. int rightnow;
  756. {
  757.     if (active_display(side) && DebugG) {
  758.     printf("To %s: update unit %s%s\n",
  759.            side_desig(side), unit_desig(unit), (rightnow ? " (now)" : ""));
  760.     }
  761. }
  762.  
  763. void
  764. update_unit_acp_display(side, unit, rightnow)
  765. Side *side;
  766. Unit *unit;
  767. int rightnow;
  768. {
  769.     if (active_display(side) && DebugG) {
  770.     printf("To %s: update unit %s acp%s\n",
  771.            side_desig(side), unit_desig(unit), (rightnow ? " (now)" : ""));
  772.     }
  773. }
  774.  
  775. /* This hook updates any realtime clock displays.  If the game does not
  776.    have any realtime constraints, this will never be called. */
  777.  
  778. void
  779. update_clock_display(side, rightnow)
  780. Side *side;
  781. int rightnow;
  782. {
  783.     if (active_display(side) && DebugG) {
  784.     printf("To %s: %d secs this turn, %d total\n",
  785.            side_desig(side), side->turntimeused, side->totaltimeused);
  786.     /* also display total game clock */
  787.     }
  788. }
  789.  
  790. void
  791. update_message_display(side, sender, str, rightnow)
  792. Side *side, *sender;
  793. char *str;
  794. int rightnow;
  795. {
  796. }
  797.  
  798. void
  799. update_everything()
  800. {
  801.     printf("Update everything!\n");
  802. }
  803.  
  804. void
  805. action_point(side, x, y)
  806. Side *side;
  807. int x, y;
  808. {
  809. }
  810.  
  811.  
  812. /* Generate a description of all the user input that is possible. */
  813.  
  814. static void
  815. describe_commands(arg, key, buf)
  816. int arg;
  817. char *key, *buf;
  818. {
  819.     struct a_cmd *cmdentry;
  820.  
  821.     for (cmdentry = cmdtable; cmdentry->cmd != NULL; ++cmdentry) {
  822.     strcat(buf, cmdentry->cmd);
  823.     strcat(buf, "\n");
  824.     }
  825. }
  826.  
  827. static void
  828. interpret_help(side, topic)
  829. Side *side;
  830. char *topic;
  831. {
  832.     HelpNode *node;
  833.  
  834.     if (side == NULL) side = defaultside;
  835.     if (side == NULL) {
  836.     fprintf(stderr, "no side to help?\n");
  837.     return;
  838.     }
  839.     if (curhelpnode == NULL) {
  840.     add_help_node("commands", describe_commands, 0, first_help_node);
  841.     curhelpnode = first_help_node;
  842.     }
  843.     switch (topic[0]) {
  844.       case 'n':
  845.     curhelpnode = curhelpnode->next;
  846.     break;
  847.       case 'p':
  848.     curhelpnode = curhelpnode->prev;
  849.     break;
  850.       case 'a':
  851.     for (node = first_help_node->next; node != first_help_node; node = node->next) {
  852.         show_help(side, node);
  853.     }
  854.     return; /* don't show cur help node too */
  855.       case '\0':
  856.     /* Note that no topic char equals '\0', so will come here. */
  857.       default:
  858.     curhelpnode = first_help_node;
  859.     break;
  860.     }
  861.     show_help(side, curhelpnode);
  862. }
  863.  
  864. /* Spew out the entire text of the current help node. */
  865.  
  866. static void
  867. show_help(side, helpnode)
  868. Side *side;
  869. HelpNode *helpnode;
  870. {
  871.     int linelen, skipchar;
  872.     char *linebegin = get_help_text(helpnode), *lineend;
  873.  
  874.     printf("Topic: %s\n", helpnode->key);
  875.     while (*linebegin != '\0') {
  876.     skipchar = 0;
  877.     lineend = (char *) strchr(linebegin, '\n');
  878.     if (lineend) skipchar = 1;
  879.     linelen = (lineend ? lineend - linebegin : strlen(linebegin));
  880.     if (linelen > 75) linelen = 75;
  881.     strncpy(spbuf, linebegin, linelen);
  882.     spbuf[linelen] = '\0';
  883.     printf("%s\n", spbuf);
  884.     linebegin += linelen + skipchar;
  885.     }
  886. }
  887.  
  888. /* This reports progress in reading GDL files. */
  889.  
  890. void
  891. announce_read_progress()
  892. {
  893. }
  894.  
  895. /* This is used for initialization steps that take a long time. */
  896.  
  897. int linemiddle = FALSE;
  898.  
  899. void
  900. announce_lengthy_process(msg)
  901. char *msg;
  902. {
  903.     printf("%s; ", msg);
  904.     fflush(stdout);
  905.     linemiddle = TRUE;
  906. }
  907.  
  908. /* Update the progress, expressing it as a percentage done. */
  909.  
  910. void
  911. announce_progress(percentdone)
  912. int percentdone;
  913. {
  914.     printf(" %d%%", percentdone);
  915.     fflush(stdout);
  916.     linemiddle = TRUE;
  917. }
  918.  
  919. /* Announce the end of the lengthy process. */
  920.  
  921. void
  922. finish_lengthy_process()
  923. {
  924.     printf(" done.\n");
  925.     linemiddle = FALSE;
  926. }
  927.  
  928. int
  929. #ifdef __STDC__
  930. schedule_movie(Side *side, enum movie_type movie, ...)
  931. #else
  932. schedule_movie(side, movie)
  933. Side *side;
  934. enum movie_type movie;
  935. #endif
  936. {
  937.     return FALSE;
  938. }
  939.  
  940. void
  941. play_movies(sidemask)
  942. SideMask sidemask;
  943. {
  944. }
  945.  
  946. void
  947. ui_save_state(side)
  948. Side *side;
  949. {
  950.     /* No state to save. */
  951. }
  952.  
  953. void
  954. flush_display_buffers(side)
  955. Side *side;
  956. {
  957.     if (active_display(side) && DebugG) {
  958.     printf("To %s: flush display buffers\n", side_desig(side));
  959.     }
  960. }
  961.  
  962. /* An init error needs to have the command re-run. */
  963.  
  964. void
  965. low_init_error(str)
  966. char *str;
  967. {
  968.     if (linemiddle) printf("\n");
  969.     fprintf(stderr, "Error: %s.\n", str);
  970.     fflush(stderr);
  971. }
  972.  
  973. /* A warning just gets displayed, no other action is taken. */
  974.  
  975. void
  976. low_init_warning(str)
  977. char *str;
  978. {
  979.     if (linemiddle) printf("\n");
  980.     fprintf(stdout, "Warning: %s.\n", str);
  981.     fflush(stdout);
  982. }
  983.  
  984. /* A run error is fatal. */
  985.  
  986. void
  987. low_run_error(str)
  988. char *str;
  989. {
  990.     if (linemiddle) fprintf(stderr, "\n");
  991.     fprintf(stderr, "Error: %s.\n", str);
  992.     fflush(stderr);
  993.     exit(1);
  994. }
  995.  
  996. /* Runtime warnings are for when it's important to bug the players,
  997.    usually a problem with Xconq or a game design. */
  998.  
  999. void
  1000. low_run_warning(str)
  1001. char *str;
  1002. {
  1003.     if (linemiddle) printf("\n");
  1004.     fprintf(stdout, "Warning: %s.\n", str);
  1005.     fflush(stdout);
  1006. }
  1007.  
  1008. void
  1009. print_form(form)
  1010. Obj *form;
  1011. {
  1012.     print_form_and_value(stdout, form);
  1013. }
  1014.  
  1015. void
  1016. end_printing_forms()
  1017. {
  1018. }
  1019.  
  1020. void
  1021. low_send(id, buf)
  1022. int id;
  1023. char *buf;
  1024. {
  1025. }
  1026.  
  1027. int
  1028. low_receive(id, buf, maxchars, timeout)
  1029. int *id, maxchars, timeout;
  1030. char *buf;
  1031. {
  1032.   return 0;
  1033. }
  1034.  
  1035. #include "imf.h"
  1036.  
  1037. void
  1038. make_generic_image_data(imf)
  1039. ImageFamily *imf;
  1040. {
  1041. }
  1042.